package com.bkd.dreams.client.event;

import java.util.Date;
import java.util.List;

import com.bkd.dreams.client.ComponentRenderer;
import com.bkd.dreams.client.event.service.VolunteerEventService;
import com.bkd.dreams.client.event.service.VolunteerEventServiceAsync;
import com.bkd.dreams.client.volunteer.VolunteerDTO;
import com.google.gwt.cell.client.ActionCell;
import com.google.gwt.cell.client.DateCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.datepicker.client.DateBox;

public class EventTable extends ComponentRenderer {

	private VerticalPanel mainPanel = new VerticalPanel();
	private CellTable<VolunteerEventDTO> eventsTable = new CellTable<VolunteerEventDTO>();
	private TextBox newEventNameTextBox = new TextBox();
	private DateBox newEventDatePicker = new DateBox();
	private Button addEventButton = new Button("Add");
	private HorizontalPanel addPanel = new HorizontalPanel();
	private VolunteerEventServiceAsync volEventSvc = GWT.create(VolunteerEventService.class);
	private VolunteerDTO volunteer = null;
	
	public void setVolunteer(VolunteerDTO volunteer) {
		this.volunteer = volunteer;
	}
	
	@Override
	public void loadTable(TabPanel tabPanel) {
		TextColumn<VolunteerEventDTO> nameColumn = new TextColumn<VolunteerEventDTO>() {
			@Override
			public String getValue(VolunteerEventDTO event) {
				return event.getName();
			}
		};
		eventsTable.addColumn(nameColumn, "Event");
		
		DateCell dateCell = new DateCell();
		Column<VolunteerEventDTO, Date> dateColumn = new Column<VolunteerEventDTO, Date>(dateCell) {
			@Override
			public Date getValue(VolunteerEventDTO event) {
				return event.getDate();
			}
		};
		eventsTable.addColumn(dateColumn, "Date");

		SignUpActionCell signUpActionCell = new SignUpActionCell(
				volunteer, new ActionCell.Delegate<VolunteerEventDTO>() {
					public void execute(VolunteerEventDTO event) {
						signUp(event);
					}

				});
		Column<VolunteerEventDTO, VolunteerEventDTO> signUpColumn = new Column<VolunteerEventDTO, VolunteerEventDTO>(signUpActionCell) {
			public VolunteerEventDTO getValue(VolunteerEventDTO event) {
				return event;
			}
		};
		eventsTable.addColumn(signUpColumn, "Sign Up");

		ActionCell<VolunteerEventDTO> actionCell = new ActionCell<VolunteerEventDTO>(
				"Remove", new ActionCell.Delegate<VolunteerEventDTO>() {
					public void execute(VolunteerEventDTO event) {
						removeEvent(event);
					}

				});
		Column<VolunteerEventDTO, VolunteerEventDTO> removeColumn = new Column<VolunteerEventDTO, VolunteerEventDTO>(actionCell) {
			public VolunteerEventDTO getValue(VolunteerEventDTO event) {
				return event;
			}
		};
		eventsTable.addColumn(removeColumn, "Remove");

		addPanel.add(newEventNameTextBox);
		addPanel.add(newEventDatePicker);
		addPanel.add(addEventButton);

		mainPanel.add(eventsTable);
		mainPanel.add(addPanel);
		
		tabPanel.add(mainPanel, "Upcoming Events");
		
		newEventNameTextBox.setFocus(true);
		
		addEventButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				addEvent();
			}
		});
		
		refreshTable();
	}

	protected void refreshTable() {
		if (volEventSvc == null) {
			volEventSvc = GWT.create(VolunteerEventService.class);
		}

		// Set up the callback object.
		AsyncCallback<List<VolunteerEventDTO>> callback = new AsyncCallback<List<VolunteerEventDTO>>() {
			public void onFailure(Throwable error) {
				handleError(error);
			}
			public void onSuccess(List<VolunteerEventDTO> result) {
				updateTable(result);
			}
		};

		// Make the call to the stock price service.
		volEventSvc.getAllEvents(callback);
	}
	
	protected void updateTable(List<VolunteerEventDTO> events) {
		eventsTable.setRowCount(events.size(),true);
		eventsTable.setRowData(0, events);
	}
	
	protected void addEvent() {
		String name = newEventNameTextBox.getText();
		Date date = newEventDatePicker.getValue();
		if(name.equals("") || date == null) {
			return;
		}
		
		VolunteerEventDTO newEvent = new VolunteerEventDTO(name,date);
		addEvent(newEvent);
		newEventNameTextBox.setText("");
		newEventDatePicker.setValue(null);		
	}
	
	protected void addEvent(VolunteerEventDTO event) {
		if (volEventSvc == null) {
			volEventSvc = GWT.create(VolunteerEventService.class);
		}

		// Set up the callback object.
		AsyncCallback<Void> callback = new AsyncCallback<Void>() {
			public void onFailure(Throwable error) {
				handleError(error);
			}

			public void onSuccess(Void result) {
				refreshTable();
			}
		};

		// Make the call to the stock price service.
		volEventSvc.addEvent(event, callback);
	}
	
	protected void removeEvent(VolunteerEventDTO event) {
		if (volEventSvc == null) {
			volEventSvc = GWT.create(VolunteerEventService.class);
		}

		// Set up the callback object.
		AsyncCallback<Void> callback = new AsyncCallback<Void>() {
			public void onFailure(Throwable error) {
				handleError(error);
			}

			public void onSuccess(Void result) {
				refreshTable();
			}
		};

		// Make the call to the stock price service.
		volEventSvc.removeEvent(event, callback);
	}

	protected void signUp(VolunteerEventDTO event) {
		if (volEventSvc == null) {
			volEventSvc = GWT.create(VolunteerEventService.class);
		}

		// Set up the callback object.
		AsyncCallback<Void> callback = new AsyncCallback<Void>() {
			public void onFailure(Throwable error) {
				handleError(error);
			}

			public void onSuccess(Void result) {
				refreshTable();
			}
		};

		// Make the call to the stock price service.
		if(event.getVolunteers().contains(volunteer.getKey())) {
			volEventSvc.removeSignUp(event, volunteer, callback);
		} else {
			volEventSvc.signUp(event, volunteer, callback);
		}
	}
}
